package com.zksw.utils.api.wechat;

import com.alibaba.fastjson.JSONObject;
import com.zksw.utils.ResourceUtil;
import com.zksw.utils.api.ApiUserUtils;
import com.zksw.utils.api.CommonUtil;
import com.qiniu.util.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import sun.awt.SunHints;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

public class GetMiniQrCode {
    private static Logger logger = Logger.getLogger(GetMiniQrCode.class);

    public static String getAccessToken() {
        String requestUrl = ApiUserUtils.getAccessToken();
        JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);

        if (null == sessionData || StringUtils.isNullOrEmpty(sessionData.getString("access_token"))) {
            logger.error("获取access_token失败！requestUrl=" + requestUrl);
            return "";
        }

        return sessionData.getString("access_token");
    }

    public static String getMiniQr(String sceneStr, String pageStr, Integer width, String accessToken) {
        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String miniQrUrl = "";
        try {
            String url = ApiUserUtils.getMiniQrCode(accessToken);
            Map<String,Object> param = new HashMap<>();
            param.put("scene", sceneStr);
            param.put("page", pageStr);
            param.put("width", width);
            param.put("auto_color", false);
            Map<String,Object> line_color = new HashMap<>();
            line_color.put("r", 0);
            line_color.put("g", 0);
            line_color.put("b", 0);
            param.put("line_color", line_color);
            logger.info("调用生成微信URL接口传参:" + param);
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity requestEntity = new HttpEntity(param, headers);
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
//            logger.info("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody());
            byte[] result = entity.getBody();
//            logger.info(Base64.encodeBase64String(result));
            inputStream = new ByteArrayInputStream(result);

            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String fileName = uuid + "_qrCode_.jpg";
            String destPath = System.getProperty("webPath") + ResourceUtil.getConfigByName("qrCodes.path") + fileName;
            logger.info("小程序码本地保存地址：" + destPath );
            File file = new File(destPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            outputStream = new FileOutputStream(file);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();

            miniQrUrl = ResourceUtil.getConfigByName("host") + ResourceUtil.getConfigByName("qrCodes.path") + fileName;
        } catch (Exception e) {
            logger.error("调用小程序生成微信永久小程序码URL接口异常",e);
        } finally {
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return miniQrUrl;
    }

    public static String mergeImgAndText(String coverImg, String qrCode, String eventText, String priceText, String nickName) {
        Font font = new Font("宋体", Font.BOLD, 30);// 添加字体的属性设置
        String mergedImgUrl = "";

        try {
            // 加载封面图片
            logger.info("coverImg: " + coverImg);
            logger.info("qrCode url: " + qrCode);
            URL coverImgUrl = new URL(coverImg);
            BufferedImage imageCover = ImageIO.read(coverImgUrl);
            // 加载小程序码图片
            URL qrCodeUrl = new URL(qrCode);
            BufferedImage imageQrCode = ImageIO.read(qrCodeUrl);
            // 以空白图片为模板
            BufferedImage image = new BufferedImage(540,
                    960, BufferedImage.TYPE_3BYTE_BGR);
            Graphics2D g = image.createGraphics();

            g.setRenderingHint(SunHints.KEY_ANTIALIASING, SunHints.VALUE_ANTIALIAS_OFF);
            g.setRenderingHint(SunHints.KEY_TEXT_ANTIALIASING, SunHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
            g.setRenderingHint(SunHints.KEY_STROKE_CONTROL, SunHints.VALUE_STROKE_DEFAULT);
            g.setRenderingHint(SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST, 140);
            g.setRenderingHint(SunHints.KEY_FRACTIONALMETRICS, SunHints.VALUE_FRACTIONALMETRICS_OFF);
            g.setRenderingHint(SunHints.KEY_RENDERING, SunHints.VALUE_RENDER_DEFAULT);

            g.setColor(Color.WHITE);
            g.fillRect(0, 0, 540, 960);
            // 绘制封面图
            g.drawImage(imageCover, 0, 0, 540, 576,null);
            // 设置文本样式
            g.setFont(font);
            //在封面图片下方添加活动名称和价格文本
            g.setColor(new Color(3, 3, 3));
            g.drawString(eventText, 20, 576 + 40);
            g.setColor(Color.RED);
            g.drawString("￥: " + priceText, 20, 576 + 80);
            // 在模板上添加小程序码(地址,左边距,上边距,图片宽度,图片高度,未知)
            g.drawImage(imageQrCode, (540 - 200) / 2, 576 + (384 - 200) / 2, 200, 200, null);
            // 截取用户名称的最后一个字符
            String lastChar = nickName.substring(nickName.length() - 1);
            // 拼接新的用户名称
            String newUserName = (nickName.length() > 2 ? nickName.substring(0, 1) + "**" + lastChar : nickName) + " 的邀请二维码";
            // 添加用户名称
            g.setColor(new Color(3, 3, 3));
            int nameWidth = g.getFontMetrics().stringWidth(newUserName);
            g.drawString(newUserName, (540 - nameWidth) / 2, 576 + (384 - 200) / 2 + 200 + 50);
            g.dispose();

            // 获取新文件的地址
            String filePath = qrCodeUrl.getPath().replaceAll("_qrCode_", "_distributionEventMergeImg_");
            String destPath = System.getProperty("webPath") /*+ ResourceUtil.getConfigByName("qrCodes.path")*/ + filePath;
            logger.info("合并后的分销活动推广图片本地保存地址：" + destPath );
            File file = new File(destPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            // 生成新的合成过的用户二维码并写入新图片
            saveImageUsingJPGWithQuality(image, file, 0.85f);
            mergedImgUrl = ResourceUtil.getConfigByName("host") /*+ ResourceUtil.getConfigByName("qrCodes.path")*/ + filePath;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("合并图片和文字失败！");
        }
        return mergedImgUrl;
    }

    /* *
     * save jpg with specified quality. 为了图片质量，quality的值不能太低。
     * */
    public static void saveImageUsingJPGWithQuality(BufferedImage image,
                                                    File file, float quality) throws Exception {

        Iterator<ImageWriter> iter = ImageIO
                .getImageWritersByFormatName("jpeg");

        ImageWriter imageWriter = iter.next();
        ImageWriteParam iwp = imageWriter.getDefaultWriteParam();

        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(quality);

        FileImageOutputStream fileImageOutput = new FileImageOutputStream(file);
        imageWriter.setOutput(fileImageOutput);
        IIOImage iio_image = new IIOImage(image, null, null);
        imageWriter.write(null, iio_image, iwp);
        fileImageOutput.flush();
        fileImageOutput.close();
        imageWriter.dispose();
    }
}
